#include "gainwidget.h"
#include "dm/dmdef.h"

GainWidget::GainWidget(const uint8_t &channel, const double &max, QWidget *parent)
    : AGroupBox{tr(LABEL_GAIN), parent}
    , m_channel{channel}
{
    bar = new PeakBar(this);
    slider = new ASlider(this);
    spinBox = new ADoubleSpinBox(this);
    speakerButton = new APushButton(this);
    phaseButton = new APushButton(this);

    auto layout = new QGridLayout(this);

    layout->addWidget(bar, 0, 0, Qt::AlignRight);
    layout->addWidget(slider, 0, 1, Qt::AlignLeft);
    layout->addWidget(spinBox, 1, 0, 1, 2, Qt::AlignHCenter);
    layout->addWidget(speakerButton, 2, 0, 1, 2, Qt::AlignHCenter);
    layout->addWidget(phaseButton, 3, 0, 1, 2, Qt::AlignHCenter);
    layout->setVerticalSpacing(15 * ratio());

    slider->setRange(GAIN_MIN / GAIN_STEP, max / GAIN_STEP);

    spinBox->setRange(GAIN_MIN, max);
    spinBox->setDecimals(GAIN_DECIMAL);
    spinBox->setSingleStep(GAIN_STEP);
    spinBox->setSuffix(tr(LABEL_DECIBEL_UINT));

    speakerButton->setIconSize(QSize(speakerButton->height() * 0.8, speakerButton->height() * 0.8));
    speakerButton->setCheckable(true);


    phaseButton->setIconSize(QSize(phaseButton->height() * 0.8, phaseButton->height() * 0.8));
    phaseButton->setCheckable(true);

    speakerButton->setStyleSheet(QString(R"(
        APushButton {
            border-radius: %1px;
            border: none;
            background-color: #2F8C00;
            icon: url(:/img/volume-on.svg);
            icon-size: %2px %2px;
        }
        /* 悬停 */
        APushButton:hover {
            background-color: #CCCCCC;
        }
        /* 鼠标按下 */
        APushButton:pressed {
            background-color: #CCCCCC;
        }
        /* 选中状态 */
        APushButton:checked {
            background-color: #CC3131;
            icon: url(:/img/volume-off.svg);
            icon-size: %2px %2px;
        }
        /* 选中状态悬停 */
        APushButton:checked:hover {
            background-color: #CCCCCC;
        }
        /* 选中状态鼠标按下 */
        APushButton:checked:pressed {
            background-color: #CCCCCC;
        }
        /* 禁用状态 */
        APushButton:disabled {
            background-color: #999999;
        }
    )").arg(4 * ratio()).arg(15 * ratio()));

    phaseButton->setStyleSheet(QString(R"(
        APushButton {
            border-radius: %1px;
            border: none;
            background-color: #FFFFFF;
            icon: url(:/img/positive.svg);
            icon-size: %2px %2px;
        }
        /* 悬停 */
        APushButton:hover {
            background-color: #CCCCCC;
        }
        /* 鼠标按下 */
        APushButton:pressed {
            background-color: #CCCCCC;
        }
        /* 选中状态 */
        APushButton:checked {
            background-color: #B8BECC;
            icon: url(:/img/negative.svg);
            icon-size: %2px %2px;
        }
        /* 选中状态悬停 */
        APushButton:checked:hover {
            background-color: #CCCCCC;
        }
        /* 选中状态鼠标按下 */
        APushButton:checked:pressed {
            background-color: #CCCCCC;
        }
        /* 禁用状态 */
        APushButton:disabled {
            background-color: #999999;
        }
    )").arg(4 * ratio()).arg(15 * ratio()));

    connect(slider, QOverload<int>::of(&QSlider::valueChanged), this, &GainWidget::sliderChanged);
    connect(spinBox, QOverload<double>::of(&ADoubleSpinBox::valueChanged), this, &GainWidget::spinBoxChanged);
    connect(speakerButton, &QPushButton::clicked, this, &GainWidget::speakerToggled);
    connect(phaseButton, &QPushButton::clicked, this, &GainWidget::phaseToggled);

}

void GainWidget::set(uint16_t gain, uint8_t speaker, uint8_t phase)
{
    blockSignals(true);

    slider->setValue(static_cast<int>(gain) + slider->minimum());

    speakerButton->setChecked(speaker);
    speakerToggled(speaker);

    phaseButton->setChecked(phase);
    phaseToggled(phase);

    blockSignals(false);
}

void GainWidget::peak(const uint8_t &value)
{
    bar->peak(value);
}

void GainWidget::sliderChanged(const int &value)
{
    spinBox->setValue(value * GAIN_STEP);
}

void GainWidget::spinBoxChanged(const double &value)
{
    slider->blockSignals(true);
    slider->setValue(value / GAIN_STEP);
    slider->blockSignals(false);
    emit gainChanged(m_channel, slider->value() - slider->minimum());
}

void GainWidget::speakerToggled(bool checked)
{
    emit speakerChanged(m_channel, checked);
}

void GainWidget::phaseToggled(bool checked)
{
    emit phaseChanged(m_channel, checked);
}

void GainWidget::setBlockSignals(bool block)
{
    slider->blockSignals(block);
    spinBox->blockSignals(block);
    speakerButton->blockSignals(block);
    phaseButton->blockSignals(block);
}
